/*
 * =====================================================================================
 *
 *       Filename:  rand-long-file.cpp
 *
 *    Description:  产生随机正数文件
 *
 *        Version:  1.0
 *        Created:  2011-11-8 16:51:53
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (),
 *        Company:
 *
 * =====================================================================================
 */

#include <fstream>
#include <sstream>
#include <ctime>
#include <cstdlib>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

//生成[a, b]内的随机数
unsigned int _rand(unsigned int a, unsigned int b)
{
    unsigned int min = std::min(a, b);
    unsigned int max = std::max(a, b);
    return min + (rand()*rand()) % (max - min + 1);
}

//产生[0, n)内不重复的m(m<=n)个正整数
void gen_longs(unsigned int m, unsigned int n)
{
    assert(m <= n);
    unsigned int *A = NULL;
    try {
        A = new unsigned int[n];
    } catch (std::bad_alloc &ba) {
        std::cout << ba.what() << std::endl;
        return ;
    }


    for (unsigned int i = 0; i < n; ++i) {
        A[i] = i;
    }

    srand(unsigned(time(NULL)));
    std::stringstream ss;
    ss << "rand-long-file-[" << m << "-" << n << "].txt";
    std::ofstream file(ss.str().c_str());

    if (!file) {
        std::cout << "open file " << ss.str() << " failed." << std::endl;
    }

    for (unsigned int i = 0; i < m; ++i) {
        std::swap(A[i], A[_rand(i, n - 1)]);
        file << A[i] << std::endl;
    }

    delete [] A;
}

int main(int argc, const char *argv[])
{
    // Declare the supported options.
    po::options_description desc("Allowed options");
    desc.add_options()
    ("help", "its generate no duplicated rand file")
    ("count", po::value<unsigned int>(), "set count level")
    ("maxcnt", po::value<unsigned int>(), "set maxcnt level")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 1;
    }

    unsigned int count = 4000000, maxcnt = 4200000;

    if (vm.count("count")) {
        count = vm["count"].as<unsigned int>();
        std::cout << "count was set to " << count << ".\n";
    } else {
        std::cout << "count was not set.\n";
    }

    if (vm.count("maxcnt")) {
        maxcnt = vm["maxcnt"].as<unsigned int>();
        std::cout << "maxcnt was set to " << maxcnt << ".\n";
    } else {
        std::cout << "maxcnt was not set.\n";
    }

    std::cout << "gen_longs" << std::endl;
    gen_longs(count, maxcnt);

    return 0;
}

